package com.chao.common.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializeFilter;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.SimplePropertyPreFilter;
import com.chao.common.util.DateUtile;
import com.chao.common.util.exception.SysException;
import net.logstash.logback.encoder.org.apache.commons.lang.StringUtils;
import org.springframework.util.DigestUtils;

import java.util.Collection;
import java.util.Date;
import java.util.Random;
import java.util.UUID;
import java.util.regex.Pattern;

/**
 * 字符串工具类
 */
public final class StrUtile {

    /**
     * 根据用户id生成token
     * 开发阶段使用 userId MD5 编码
     * 上线后 使用 userId+当天日期 生成编码
     */
    public static String getToken(String userId,String loginType){
        return getMD5(userId+loginType);
    }

    /**
     * 获取记录主键  格式 yyyyMMddHHmmssSSS + 三位随机数
     */
    public static String getId(){
        try {
            //防止重复 休眠1毫秒
            Thread.sleep(1);
        }catch (Exception e){}
        return DateUtile.dateToString(new Date(),"yyyyMMddHHmmssSSS")+(Math.abs(new Random().nextInt()%900)+100);
    }

    /**
     * 获取UUID
     */
    public static String getUUID(){
        return UUID.randomUUID().toString().replace("-","").toUpperCase();
    }

    /**
     * 封装默认分页参数
     */
    public static JSONObject getPageJson(JSONObject json){
        if(!json.containsKey("page") && !json.containsKey("size")){
            return json;
        }
        if(!json.containsKey("page")){
            json.put("page",1);
        }
        if(!json.containsKey("size")){
            json.put("size",10);
        }
        return json;
    }

    /**
     * 判断字符串是否为空
     * 返回 true表示字符串为空
     * 返回 false表示字符串非空
     */
    public static boolean isEmpty(String str){
        return StringUtils.isBlank(str) || "undefined".equals(str) || "null".equals(str);
    }

    /**
     * 判断对象是否为空
     * 返回 true表示对象为空
     * 返回 false表示对象非空
     */
    public static boolean isEmpty(Object str){
        return null == str || "".equals(str) || "undefined".equals(str) || "null".equals(str);
    }

    /**
     * 对字符串进行MD5编码
     */
    public static String getMD5(String str){
        return DigestUtils.md5DigestAsHex(str.getBytes());
    }

    /**
     * 校验数字是否为正整数
     */
    public static boolean isNumeric(String string){
        Pattern pattern = Pattern.compile("[0-9]*");
        return pattern.matcher(string).matches();
    }

    /**
     * 合并对象 将obj1里的内容合并到obj中转为json  如果字段重合 则保留obj1里的内容
     */
    public static JSONObject mergeObj(Object obj,Object obj1){
        if(isEmpty(obj) && isEmpty(obj1)) {
            return new JSONObject();
        }
        JSONObject json;
        if(!isEmpty(obj) && isEmpty(obj1)) {
            return (JSONObject) JSON.toJSON(obj);
        }else if(isEmpty(obj) && !isEmpty(obj1)) {
            return (JSONObject) JSON.toJSON(obj1);
        }else{
            json = (JSONObject) JSON.toJSON(obj);
            JSONObject json1 = (JSONObject) JSON.toJSON(obj1);
            json1.forEach((key,value) -> {
                if(!isEmpty(json1.get(key))){
                    json.put(key,json1.get(key));
                }
            });
        }
        return json;
    }

    public static JSONObject getSelectTime(JSONObject params,boolean flag){
        //判断开始结束时间 默认按 yyyy-MM-dd 查询 如有特殊 则传  字段标明
        String startTime = params.getString("startTime");
        String endTime = params.getString("endTime");
        if(flag){
            if (StrUtile.isEmpty(startTime)) {
                throw new SysException("请输入开始日期！");
            }
            if (StrUtile.isEmpty(endTime)) {
                throw new SysException("请输入结束日期！");
            }
        }
        if (!StrUtile.isEmpty(startTime) || !StrUtile.isEmpty(endTime)) {
            if (StrUtile.isEmpty(startTime)) {
                throw new SysException("请输入开始日期！");
            }
            if (StrUtile.isEmpty(endTime)) {
                throw new SysException("请输入结束日期！");
            }
            Date start;
            Date end;
            if(params.containsKey("dateFormat")){
                start = DateUtile.stringToDate(startTime,params.getString("dateFormat"));
                end = DateUtile.stringToDate(endTime,params.getString("dateFormat"));
            }else{
                start = DateUtile.getHmd(startTime);
                end = DateUtile.editD(DateUtile.getHmd(endTime),1);
            }
            if (DateUtile.editD(start,31).getTime() < end.getTime()) {
                throw new SysException("起始时间间隔不能超过31天");
            }
            params.put("startTime", DateUtile.toYmdhms(start));
            params.put("endTime", DateUtile.toYmdhms(end));
        }
        return params;
    }

    public static String toJSONString(Object object, String... filterFields) {
        if (filterFields != null && filterFields.length > 0) {
            SimplePropertyPreFilter filter = new SimplePropertyPreFilter();
            for (String field : filterFields) {
                filter.getExcludes().add(field);
            }
            SerializeFilter[] filters = {filter};
            return JSON.toJSONString(object, filters,
                    SerializerFeature.WriteMapNullValue);
        }
        return JSON.toJSONString(object,
                SerializerFeature.WriteMapNullValue,
                SerializerFeature.WriteNullListAsEmpty);
    }

    /**
     * 封装时间查询条件
     */
    public static JSONObject getSelectTime(JSONObject params){
        return getSelectTime(params,false);
    }

    /**
     * 逗号将集合拼接为字符串
     */
    public static String join(Collection<?> iterable, String separator){
        return StringUtils.join(iterable,separator);
    }

    /**
     * 查询字符串s在str中的数量
     */
    public static int getStrSize(String s, String str) {
        if(s.equals(str)){
            return 1;
        }
        int i = str.split(s).length-1;
        if(i == 0 && str.contains(s)){
            return 1;
        }
        return i;
    }
}
